package com.example.demo.web.filter;


import java.io.IOException;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.web.filter.PathMatchingFilter;
import org.apache.shiro.web.util.WebUtils;

/**
 * 表单过滤器处理类,自行扩展类
 * <p>@author Henry.Y</p>
 * <p>@date 2019-08-02</p>
 */
public class FormLoginFilter extends PathMatchingFilter{

	private String loginUrl= "/login.jsp";     //登陆界面地址
	
	private String successUrl= "/";            //登陆成功地址
	
	/**
	 * 再次对客户请求进行验证,如果是登录请求，则继续进行登陆处理，如果不是则重定向至登陆界面
	 * @param reqeust 请求
	 * @param response 响应
	 * @param mappedValue 接收配置文件中的绑定参数*[*]
	 * @return true:继续过滤器链,false:停止过滤器链
	 */
	protected boolean onPreHandle(ServletRequest request,ServletResponse response,Object mappedValue)throws Exception{
		if(SecurityUtils.getSubject().isAuthenticated()){
			return true;      //已经登陆过了
		}
		HttpServletRequest httpRequest= (HttpServletRequest)request;
		HttpServletResponse httpResponse= (HttpServletResponse)response;
		if(isLoginRequest(httpRequest)){
			if("post".equalsIgnoreCase(httpRequest.getMethod())){   //进行form表单,判断是否是post请求
				boolean loginSuccess= login(httpRequest);           //登陆,进行登陆操作
				if(loginSuccess){
					return redirectToSuccessUrl(httpRequest,httpResponse);    //登陆成功,重定向向成功界面
				}
				return true;    //继续过滤器链
			}
		}else{
			saveRequestAndRedirectToLogin(httpRequest,httpResponse);          //如果不是登陆请求,保存请求,且重定向到登陆请求
			return false;       //停止过滤
		}
		return true;            //继续过滤
	}
	
	/**
	 * 登陆成功后重定向主页
	 * @param request 请求
	 * @param response 响应
	 * @return fasle 停止过滤器链
	 * @throws IOException io读写异常
	 */
	private boolean redirectToSuccessUrl(HttpServletRequest request,HttpServletResponse response)throws IOException{
		WebUtils.redirectToSavedRequest(request, response, successUrl);
		return false;
	}
	
	/**
	 * 保存请求,重定向至登陆界面
	 * @param request 请求
	 * @param response 响应
	 * @throws IOException io读写异常
	 */
	private void saveRequestAndRedirectToLogin(HttpServletRequest request,HttpServletResponse response)throws IOException{
		WebUtils.saveRequest(request);                              //保存请求
		WebUtils.issueRedirect(request, response, loginUrl);        //重定向登陆界面
	}
	
	/**
	 * 判断请求是否是登录请求
	 * @param request 请求
	 * @return true:登录请求;false:不是登录请求
	 */
	private boolean isLoginRequest(HttpServletRequest request){
	    return pathsMatch(loginUrl,WebUtils.getPathWithinApplication(request));
	}
	
	/**
	 * 登陆方法
	 * @param request 请求
	 * @return true:登陆成功;false:登陆失败
	 */
	private boolean login(HttpServletRequest request){
		String username= request.getParameter("username");           //获取用户姓名
		String password= request.getParameter("password");           //获取用户密码
		try{
			SecurityUtils.getSubject().login(new UsernamePasswordToken(username,password));     //进行登陆验证
		}catch(Exception e){
			request.setAttribute("shiroLoginFailure",e.getClass());                             //发送登陆错误信息
			return false;                                                                       //登陆失败
		}
		return true;                                                                            //登陆成功
	}
}
